﻿// SilverlightBridge
// Copyright (c) 2009
// by OpenLight Group
// http://openlightgroup.net/
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
//
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.

using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using FileManager.Files;
using System.ServiceModel;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.IO.IsolatedStorage;
using System.IO;

namespace FileManager
{
    public partial class MainPage_OOB : UserControl
    {
        #region Global Variables
        public bool IsAuthenticated = false;
        ObservableCollection<Folder> colFolders;
        private ConfirmDelete ConfirmDeleteWindow;
        private ConfirmDeleteFile ConfirmDeleteFileWindow;
        private InformationPopup InformationPopupWindow;
        private EditFolderPopup EditFolderPopupWindow;
        private FileUploadPopup FileUploadPopupWindow;
        private LoginPopup LoginPopupWindow;
        public int intPortalID = 0;
        public int intModuleID = 0;
        public int intUserID = 0;
        public int CurrentlySelectedFolderID = 0;
        public string strPassword = "";
        public string strWebServiceBase = "";
        int intLastUsedLocalFolderID = -2;
        int intCurrentFileID = -1;
        #endregion

        public MainPage_OOB()
        {
            // Required to initialize variables
            InitializeComponent();

            SetupPopups();
            ShowRootFolders();
        }

        #region SetupPopups
        private void SetupPopups()
        {
            // Set-up the Confirm Delete Window
            ConfirmDeleteWindow = new ConfirmDelete();
            ConfirmDeleteWindow.Closed += new EventHandler(ConfirmDelete_Closed);

            // Set-up the Confirm Delete File Window
            ConfirmDeleteFileWindow = new ConfirmDeleteFile();
            ConfirmDeleteFileWindow.Closed += new EventHandler(ConfirmDeleteFile_Closed);

            // Set-up the FileUploadPopup Window
            FileUploadPopupWindow = new FileUploadPopup();
            FileUploadPopupWindow.Closed += new EventHandler(FileUploadPopup_Closed);

            // Set-up the Edit Folder Window
            EditFolderPopupWindow = new EditFolderPopup();
            EditFolderPopupWindow.Closed += new EventHandler(EditFolderPopupWindow_Closed);

            // Set-up Information Popup Window
            InformationPopupWindow = new InformationPopup();

            // Set-up Login Popup Window
            LoginPopupWindow = new LoginPopup();
            LoginPopupWindow.Closed += new EventHandler(LoginPopupWindow_Closed);
        }
        #endregion

        // Login

        #region LoginPopupWindow_Closed
        void LoginPopupWindow_Closed(object sender, EventArgs e)
        {
            if (LoginPopupWindow.IsAuthenticated)
            {
                // Set global values
                IsAuthenticated = LoginPopupWindow.IsAuthenticated;
                strWebServiceBase = LoginPopupWindow.Server.Replace("Webservice.asmx", "");
                intUserID = LoginPopupWindow.UserID;
                strPassword = LoginPopupWindow.OOBPassword;

                // Save to Isolated Storage
                // Create an instance of IsolatedStorageSettings
                IsolatedStorageSettings userSettings = IsolatedStorageSettings.ApplicationSettings;

                // First Clear Isolated Storage
                ClearIsolatedStorage();

                // Add values
                userSettings.Add("WebServiceBase", strWebServiceBase);
                userSettings.Add("UserID", intUserID);
                userSettings.Add("Password", strPassword);

                GetOOBRootServerFolder();
            }
        }
        #endregion

        #region GetOOBRootServerFolder
        private void GetOOBRootServerFolder()
        {
            WebServiceSoapClient objWebServiceSoapClient = new WebServiceSoapClient();
            EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceBase + "Webservice.asmx");
            objWebServiceSoapClient.Endpoint.Address = MyEndpointAddress;

            objWebServiceSoapClient.GetOOBRootServerFolderIDCompleted += new EventHandler<GetOOBRootServerFolderIDCompletedEventArgs>(objWebServiceSoapClient_GetOOBRootServerFolderIDCompleted);
            objWebServiceSoapClient.GetOOBRootServerFolderIDAsync(intPortalID, intModuleID, intUserID, strPassword);
        }

        void objWebServiceSoapClient_GetOOBRootServerFolderIDCompleted(object sender, GetOOBRootServerFolderIDCompletedEventArgs e)
        {
            // Update the Server root folder with the proper ID
            var RootFolder = (from folders in colFolders
                              where folders.FolderID == 0
                              select folders).FirstOrDefault();

            RootFolder.FolderID = e.Result;
            CurrentlySelectedFolderID = e.Result;
            DisplayFilesInFolder();
        }
        #endregion

        // Isolated Storage

        #region ClearIsolatedStorage
        void ClearIsolatedStorage()
        {
            // Create an instance of IsolatedStorageSettings
            IsolatedStorageSettings userSettings = IsolatedStorageSettings.ApplicationSettings;
            userSettings.Remove("WebServiceBase");
            userSettings.Remove("UserID");
            userSettings.Remove("Password");
        }
        #endregion

        #region LoadFromIsolatedStorage
        void LoadFromIsolatedStorage()
        {
            // Create an instance of IsolatedStorageSettings
            IsolatedStorageSettings userSettings = IsolatedStorageSettings.ApplicationSettings;

            if (userSettings.Contains("WebServiceBase"))
            {
                try
                {
                    strWebServiceBase = Convert.ToString(userSettings["WebServiceBase"]);
                }
                catch
                {
                }
            }


            if (userSettings.Contains("UserID"))
            {
                try
                {
                    intUserID = Convert.ToInt32(userSettings["UserID"]);
                }
                catch
                {
                }
            }


            if (userSettings.Contains("Password"))
            {
                try
                {
                    strPassword = Convert.ToString(userSettings["Password"]);
                }
                catch
                {
                }
            }
        }
        #endregion

        // ****************************************
        //  Folders
        // ****************************************

        // Show Folders

        #region ShowRootFolders
        private void ShowRootFolders()
        {
            string MyDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            colFolders = new ObservableCollection<Folder>();

            // Add the Folder
            Folder LocalFolder = new Folder();
            LocalFolder.FolderID = -1;
            LocalFolder.ParentFolderID = 0;
            LocalFolder.FolderName = "Local";
            LocalFolder.isLocal = true;
            LocalFolder.FullPath = MyDocumentsPath;
            LocalFolder.SubFolders = new ObservableCollection<Folder>();
            colFolders.Add(LocalFolder);

            Folder ServerFolder = new Folder();
            ServerFolder.FolderID = 0;
            ServerFolder.ParentFolderID = 0;
            ServerFolder.FolderName = "Server";
            ServerFolder.isLocal = false;
            ServerFolder.SubFolders = new ObservableCollection<Folder>();
            colFolders.Add(ServerFolder);

            FolderTree.ItemsSource = colFolders;
        }
        #endregion

        #region GetSubFolders
        private void GetSubFolders(int intParentFolder)
        {
            WebServiceSoapClient objWebServiceSoapClient = new WebServiceSoapClient();
            EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceBase + "Webservice.asmx");
            objWebServiceSoapClient.Endpoint.Address = MyEndpointAddress;

            objWebServiceSoapClient.GetFoldersCompleted += new EventHandler<GetFoldersCompletedEventArgs>(objWebServiceSoapClient_GetSubFoldersCompleted);
            objWebServiceSoapClient.GetFoldersAsync(intParentFolder, intPortalID, intModuleID, intUserID, strPassword);
        }

        void objWebServiceSoapClient_GetSubFoldersCompleted(object sender, GetFoldersCompletedEventArgs e)
        {
            // Add the Folders
            ObservableCollection<Folder> colNewFolders = new ObservableCollection<Folder>();

            try
            {
                colNewFolders = e.Result;
            }
            catch (Exception)
            {
                waitingIcon.IsBusy = false;
                LoginPopupWindow.ResetLoginPopup();
                LoginPopupWindow.Show();
                return;
            }

            foreach (var objAdditionalFolder in colNewFolders)
            {
                // Get the Selected Folder
                Folder objParentFolder = (Folder)FolderTree.SelectedItem;

                // Only add if the selected folder is the Parent Folder
                // User could have changed the selected folder before the webservice method returned
                if (objParentFolder.FolderID == objAdditionalFolder.ParentFolderID)
                {
                    // Only add a folder if it does not already exist in the FolderTree
                    if (objParentFolder.SubFolders.FirstOrDefault(x => x.FolderID == objAdditionalFolder.FolderID) == null)
                    {
                        objParentFolder.SubFolders.Add(objAdditionalFolder);
                    }
                }
            }
        }
        #endregion

        #region AddFolder_Click
        private void AddFolder_Click(object sender, RoutedEventArgs e)
        {
            // Get the selected Folder
            Folder objFolder = (Folder)FolderTree.SelectedItem;

            // Show the Edit Folder Popup
            EditFolderPopupWindow.Title = String.Format("Add Folder", objFolder.FolderName);
            EditFolderPopupWindow.txtFolderName.Text = "";
            EditFolderPopupWindow.Show();
        }

        void objWebServiceSoapClient_AddFolderCompleted(object sender, AddFolderCompletedEventArgs e)
        {
            Folder objAddFolder = (Folder)e.Result;

            // FolderID must be more than -1 to be successful
            if (objAddFolder.FolderID > -1)
            {
                // Get the Selected Folder
                Folder objParentFolder = (Folder)FolderTree.SelectedItem;

                // Only add if the selected folder is the Parent Folder
                // User could have changed the selected folder before the webservice method returned
                if (objParentFolder.FolderID == objAddFolder.ParentFolderID)
                {
                    // Add the Folder
                    Folder objNewFolder = new Folder();
                    objNewFolder.FolderID = objAddFolder.FolderID;
                    objNewFolder.ParentFolderID = objAddFolder.ParentFolderID;
                    objNewFolder.FolderName = objAddFolder.FolderName;
                    objNewFolder.SubFolders = new ObservableCollection<Folder>();
                    objParentFolder.SubFolders.Add(objNewFolder);
                }
            }

            SetButtons("Default");
        }
        #endregion

        #region SetButtons
        private void SetButtons(string View)
        {
            switch (View)
            {
                case "Default":
                    EditFolder.Visibility = Visibility.Visible;
                    AddFolder.Content = GetFolderAddIcon();
                    DeleteFolder.Visibility = Visibility.Visible;
                    separator.Visibility = Visibility.Visible;
                    AddFile.Visibility = Visibility.Visible;
                    DeleteFile.Visibility = Visibility.Visible;
                    break;
                case "Add Folder":
                    EditFolder.Visibility = Visibility.Collapsed;
                    AddFolder.Content = "Add";
                    DeleteFolder.Visibility = Visibility.Collapsed;
                    separator.Visibility = Visibility.Collapsed;
                    AddFile.Visibility = Visibility.Collapsed;
                    DeleteFile.Visibility = Visibility.Collapsed;
                    break;
            }
        }
        #endregion

        #region btnCancel_Click
        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            SetButtons("Default");
        }
        #endregion

        #region GetFolderAddIcon
        private static Image GetFolderAddIcon()
        {
            Image folder_add = new Image();
            Uri uri = new Uri("images/folder_add.png", UriKind.Relative);
            folder_add.Source = new System.Windows.Media.Imaging.BitmapImage(uri);
            return folder_add;
        }
        #endregion

        // Local Folders and Files

        #region GetLocalSubFolders
        private void GetLocalSubFolders(Folder objParentFolder)
        {
            try
            {
                // Add all directories at this directory.
                DirectoryInfo objDirectoryInfo = new DirectoryInfo(objParentFolder.FullPath);

                foreach (DirectoryInfo di in objDirectoryInfo.EnumerateDirectories().OrderBy(x => x.Name))
                {
                    // Only add a folder if it does not already exist in the FolderTree
                    if (objParentFolder.SubFolders.FirstOrDefault(x => x.FullPath == di.FullName) == null)
                    {
                        // Add the Folder
                        Folder objAdditionalFolder = new Folder();
                        objAdditionalFolder.FolderID = intLastUsedLocalFolderID--;
                        objAdditionalFolder.ParentFolderID = objParentFolder.FolderID;
                        objAdditionalFolder.FolderName = di.Name;
                        objAdditionalFolder.isLocal = true;
                        objAdditionalFolder.FullPath = di.FullName;
                        objAdditionalFolder.SubFolders = new ObservableCollection<Folder>();

                        // only add if the directory can be enumerated
                        try
                        {
                            int tmpCount = di.EnumerateDirectories().Count();
                            objParentFolder.SubFolders.Add(objAdditionalFolder);
                        }
                        catch
                        {
                            // This is a local directory we cannot view
                        }
                    }

                }
            }
            catch
            {
                return;
            }
        }
        #endregion

        #region ShowLocalFilesInFolder
        private void ShowLocalFilesInFolder(Folder objParentFolder)
        {
            try
            {
                // Add the Files
                ObservableCollection<SilverlightFile> colFiles = new ObservableCollection<SilverlightFile>();

                // Clear the current files
                this.FileDetailList.FilesInList.Children.Clear();

                // Get Directory
                DirectoryInfo objDirectoryInfo = new DirectoryInfo(objParentFolder.FullPath);

                // Add Files to Panel
                foreach (FileInfo fi in objDirectoryInfo.EnumerateFiles().OrderBy(x => x.Name))
                {
                    FileObject objFileObject = new FileObject(FormatFileName(fi.Name), true);
                    objFileObject.IsLocal = true;
                    objFileObject.FileID = intCurrentFileID--;
                    objFileObject.FullFileName = fi.Name;
                    objFileObject.ShortFileName = FormatFileName(fi.Name);
                    objFileObject.LocalFileNameAndPath = fi.FullName;
                    ToolTipService.SetToolTip(objFileObject.DownloadIcon, "");
                    objFileObject.lnkDownload.Visibility = Visibility.Collapsed;
                    objFileObject.MouseLeftButtonDown += new MouseButtonEventHandler(objFrameworkElement_MouseLeftButtonDown);

                    this.FileDetailList.FilesInList.Children.Add(objFileObject);
                }
            }
            catch
            {
                return;
            }
        }
        #endregion

        // Edit Folders

        #region EditFolderPopupWindow_Closed
        void EditFolderPopupWindow_Closed(object sender, EventArgs e)
        {
            // This can be called from a Folder Edit or a Folder Add
            if (EditFolderPopupWindow.DialogResult != null)
            {
                if (Convert.ToBoolean(EditFolderPopupWindow.DialogResult))
                {
                    // Get the selected Folder
                    Folder objFolder = (Folder)FolderTree.SelectedItem;
                    WebServiceSoapClient objWebServiceSoapClient = new WebServiceSoapClient();
                    EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceBase + "Webservice.asmx");
                    objWebServiceSoapClient.Endpoint.Address = MyEndpointAddress;

                    if (EditFolderPopupWindow.Title.ToString() == "Add Folder")
                    {
                        // Adding a Folder
                        objWebServiceSoapClient.AddFolderCompleted += new EventHandler<AddFolderCompletedEventArgs>
                            (objWebServiceSoapClient_AddFolderCompleted);
                        objWebServiceSoapClient.AddFolderAsync
                            (
                            intPortalID,
                            intModuleID,
                            intUserID,
                            strPassword,
                            objFolder.FolderID,
                            EditFolderPopupWindow.txtFolderName.Text
                            );
                    }
                    else
                    {
                        // Folder Edit
                        objWebServiceSoapClient.UpdateFolderCompleted += new EventHandler<UpdateFolderCompletedEventArgs>
                                (objWebServiceSoapClient_UpdateFolderCompleted);
                        objWebServiceSoapClient.UpdateFolderAsync
                            (
                            intPortalID,
                            intModuleID,
                            intUserID,
                            strPassword,
                            objFolder.FolderID,
                            EditFolderPopupWindow.txtFolderName.Text
                            );
                    }
                }
            }
        }
        #endregion

        // Delete Folder

        #region DeleteFolder_Click
        private void DeleteFolder_Click(object sender, RoutedEventArgs e)
        {
            // Get the selected Folder
            Folder objFolder = (Folder)FolderTree.SelectedItem;

            // Delete Folder
            if (objFolder.ParentFolderID > 0)
            {
                ConfirmDeleteWindow.Title = "Are You sure you want to Delete?";
                ConfirmDeleteWindow.Show();
            }
            else
            {
                // Cannot delete the Root folder or My Computer folder
                InformationPopupWindow.Title = String.Format("'{0}' cannot be deleted", objFolder.FolderName);
                InformationPopupWindow.Show();
            }
        }

        private void ConfirmDelete_Closed(object sender, EventArgs e)
        {
            // Was there a response at all?
            if (ConfirmDeleteWindow.DialogResult != null)
            {
                // The User clicked Yes
                if (Convert.ToBoolean(ConfirmDeleteWindow.DialogResult))
                {
                    // Get the selected Folder
                    Folder objFolder = (Folder)FolderTree.SelectedItem;

                    WebServiceSoapClient objWebServiceSoapClient = new WebServiceSoapClient();
                    EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceBase + "Webservice.asmx");
                    objWebServiceSoapClient.Endpoint.Address = MyEndpointAddress;

                    objWebServiceSoapClient.DeleteFolderCompleted += new EventHandler<DeleteFolderCompletedEventArgs>(objWebServiceSoapClient_DeleteFolderCompleted);
                    objWebServiceSoapClient.DeleteFolderAsync(intPortalID, intModuleID, intUserID, strPassword, objFolder.FolderID);
                }
            }
        }

        void objWebServiceSoapClient_DeleteFolderCompleted(object sender, DeleteFolderCompletedEventArgs e)
        {
            // Get the Deleted folderId
            int intDeletedFolderID = e.Result;

            // Get the Selected Folder
            Folder objDeletedFolder = (Folder)FolderTree.SelectedItem;

            // Only delete if the selected folder is the Deleted Folder
            // User could have changed the selected folder before the webservice method returned
            if (objDeletedFolder.FolderID == intDeletedFolderID)
            {
                // Get the Parent Folder
                // The Parent is the Folder that has a Parent of 0 and a FolderID that is NOT -1 (-1 is the MyComputer Folder)
                Folder objParentFolder = (from Folders in colFolders.AsQueryable()
                                          where Folders.ParentFolderID == 0
                                          where Folders.FolderID > -1
                                          select Folders).FirstOrDefault().GetAllFolders().FirstOrDefault(x => x.FolderID == objDeletedFolder.ParentFolderID);

                // If Parent is not found it is probably the root folder
                // Try again with a different query
                if (objParentFolder == null)
                {
                    objParentFolder = colFolders.FirstOrDefault(x => x.FolderID == objDeletedFolder.ParentFolderID);
                }

                // Remove the folder from the Parent
                objParentFolder.SubFolders.Remove(objDeletedFolder);
            }
        }
        #endregion

        // Edit Folder

        #region EditFolder
        private void EditFolder_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // Get the selected Folder
            Folder objFolder = (Folder)FolderTree.SelectedItem;

            // Do not allow a Level 1 folde rto be edited
            if (objFolder.ParentFolderID == 0)
            {
                InformationPopupWindow.Title = "Root folders cannot be edited";
                InformationPopupWindow.Show();
                return;
            }

            // Show the Edit Folder Popup
            EditFolderPopupWindow.Title = "Edit Folder";
            EditFolderPopupWindow.txtFolderName.Text = String.Format("{0}", objFolder.FolderName);
            EditFolderPopupWindow.Show();
        }

        void objWebServiceSoapClient_UpdateFolderCompleted(object sender, UpdateFolderCompletedEventArgs e)
        {
            // Get the Selected Folder
            Folder objRenamedFolder = (Folder)FolderTree.SelectedItem;
            objRenamedFolder.FolderName = e.Result;
        }
        #endregion

        // ****************************************
        //  Files
        // ****************************************

        #region FolderTree_SelectedItemChanged
        private void FolderTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            // This method is fired by clicking on a node or when a node is
            // populated in the Tree
            DisplayFilesInFolder();
        }
        #endregion

        #region DisplayFilesInFolder
        internal void DisplayFilesInFolder()
        {
            // Get the selected Folder
            Folder objFolder = (Folder)FolderTree.SelectedItem;

            pnlEditOptions.Visibility = (objFolder.FolderID < 0) ? Visibility.Collapsed : Visibility.Visible;

            // ** If the Folder is the MyComputer Folder **
            if (objFolder.FolderID < 0)
            {
                // Clear the current files
                this.FileDetailList.FilesInList.Children.Clear();

                // This is a local folder
                GetLocalSubFolders(objFolder);
                ShowLocalFilesInFolder(objFolder);
            }
            else
            {
                if (IsAuthenticated)
                {
                    // This is a normal Server Folder
                    GetSubFolders(objFolder.FolderID);
                    ShowFilesInFolder(objFolder.FolderID);
                }
                else
                {
                    // User has not logged into the server

                    // Try to get Authentication values from IsolatedStorage
                    LoadFromIsolatedStorage();

                    // If there is a valeu from web service base
                    // Try to authenticate
                    if (strWebServiceBase.Length > 1)
                    {
                        // Try to Authenticate by calling the WhoAmI web method
                        WebServiceSoapClient objWebServiceSoapClient = new WebServiceSoapClient();
                        EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceBase + "Webservice.asmx");
                        objWebServiceSoapClient.Endpoint.Address = MyEndpointAddress;

                        objWebServiceSoapClient.WhoIAmCompleted += new EventHandler<WhoIAmCompletedEventArgs>(objWebServiceSoapClient_WhoIAmCompleted);
                        objWebServiceSoapClient.WhoIAmAsync(0, 0, intUserID, strPassword);
                        waitingIcon.IsBusy = true;
                    }
                    else
                    {
                        LoginPopupWindow.ResetLoginPopup();
                        LoginPopupWindow.Show();
                    }
                }
            }
        }

        void objWebServiceSoapClient_WhoIAmCompleted(object sender, WhoIAmCompletedEventArgs e)
        {
            UserInfo objUserInfo = new UserInfo();
            waitingIcon.IsBusy = false;
            try
            {
                objUserInfo = (UserInfo)e.Result;
            }
            catch (Exception)
            {
                waitingIcon.IsBusy = false;
                LoginPopupWindow.ResetLoginPopup();
                LoginPopupWindow.Show();
                return;
            }

            // If user is -1 then Authentication failed
            if (objUserInfo.UserID == -1)
            {
                // Show Login Popup
                LoginPopupWindow.ResetLoginPopup();
                LoginPopupWindow.Show();
            }
            else
            {
                // Authentication was successful
                IsAuthenticated = true;
                GetOOBRootServerFolder();
            }
        }
        #endregion

        #region ShowFilesInFolder
        private void ShowFilesInFolder(int FolderID)
        {
            WebServiceSoapClient objWebServiceSoapClient = new WebServiceSoapClient();
            EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceBase + "Webservice.asmx");
            objWebServiceSoapClient.Endpoint.Address = MyEndpointAddress;

            objWebServiceSoapClient.GetFilesCompleted += new EventHandler<GetFilesCompletedEventArgs>(objWebServiceSoapClient_GetFilesCompleted);
            objWebServiceSoapClient.GetFilesAsync(FolderID, intPortalID, intModuleID, intUserID, strPassword);

            // Set this as the currently selected folder
            CurrentlySelectedFolderID = FolderID;
        }

        void objWebServiceSoapClient_GetFilesCompleted(object sender, GetFilesCompletedEventArgs e)
        {
            // Add the Files
            ObservableCollection<SilverlightFile> colFiles = new ObservableCollection<SilverlightFile>();

            try
            {
                colFiles = e.Result;
            }
            catch (Exception)
            {
                waitingIcon.IsBusy = false;
                LoginPopupWindow.ResetLoginPopup();
                LoginPopupWindow.Show();
                return;
            }

            // Clear the current files
            this.FileDetailList.FilesInList.Children.Clear();

            // Add Files to Panel
            foreach (var item in colFiles.OrderBy(x => x.FileName))
            {
                string strDownloadURL =
                    String.Format(@"{0}DownloadFile.aspx?PortalID={1}&ModuleId={2}&UserID={3}&Password={4}&FileID={5}",
                    strWebServiceBase,
                    intPortalID.ToString(),
                    intModuleID.ToString(),
                    intUserID.ToString(),
                    strPassword,
                    item.FileID.ToString());

                FileObject objFileObject = new FileObject(FormatFileName(item.FileName), false);
                objFileObject.IsLocal = false;
                objFileObject.FileID = item.FileID;
                objFileObject.FullFileName = item.FileName;
                objFileObject.ShortFileName = FormatFileName(item.FileName);
                objFileObject.LocalFileNameAndPath = "";
                objFileObject.lnkDownload.NavigateUri = new Uri(strDownloadURL, UriKind.RelativeOrAbsolute);
                objFileObject.MouseLeftButtonDown += new MouseButtonEventHandler(objFrameworkElement_MouseLeftButtonDown);

                this.FileDetailList.FilesInList.Children.Add(objFileObject);
            }
        }

        #region FormatFileName
        private string FormatFileName(string strFileName)
        {
            string strFileNameResult = strFileName;

            if (strFileName != "")
            {
                if (strFileNameResult.Length > 18)
                {
                    strFileNameResult = String.Format("{0} ...", strFileNameResult.Substring(0, 15));
                }
            }

            return strFileNameResult;
        }
        #endregion

        #endregion

        #region DeleteFile_Click
        private void DeleteFile_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // Get the selected File
            FileObject objFileObject = (from File in this.FileDetailList.FilesInList.Children.AsQueryable().Cast<FileObject>()
                                        where File.SeletedFile == true
                                        where File.IsLocal == false
                                        select File).FirstOrDefault();
            // Delete File
            if (objFileObject != null)
            {
                ConfirmDeleteFileWindow.lblFileName.Content = String.Format("Delete {0} ?", objFileObject.FullFileName);
                ConfirmDeleteFileWindow.Show();
            }
            else
            {
                // Cannot delete File
                InformationPopupWindow.Title = "No file selected.";
                InformationPopupWindow.Show();
            }
        }

        private void ConfirmDeleteFile_Closed(object sender, EventArgs e)
        {
            // Was there a response at all?
            if (ConfirmDeleteFileWindow.DialogResult != null)
            {
                // The User clicked Yes
                if (Convert.ToBoolean(ConfirmDeleteFileWindow.DialogResult))
                {
                    // Get the selected File
                    FileObject objFileObject = (from File in this.FileDetailList.FilesInList.Children.AsQueryable().Cast<FileObject>()
                                                where File.SeletedFile == true
                                                where File.IsLocal == false
                                                select File).FirstOrDefault();

                    WebServiceSoapClient objWebServiceSoapClient = new WebServiceSoapClient();
                    EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceBase + "Webservice.asmx");
                    objWebServiceSoapClient.Endpoint.Address = MyEndpointAddress;

                    objWebServiceSoapClient.DeleteFileCompleted += new EventHandler<DeleteFileCompletedEventArgs>(objWebServiceSoapClient_DeleteFileCompleted);
                    objWebServiceSoapClient.DeleteFileAsync(intPortalID, intModuleID, intUserID, strPassword, objFileObject.FileID);
                }
            }
        }

        void objWebServiceSoapClient_DeleteFileCompleted(object sender, DeleteFileCompletedEventArgs e)
        {
            DisplayFilesInFolder();
        }
        #endregion

        #region AddFile_Click
        private void AddFile_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // Get the selected Folder
            Folder objFolder = (Folder)FolderTree.SelectedItem;

            // Do not allow uploads to the Local Folders
            if (objFolder.FolderID < 0)
            {
                InformationPopupWindow.Title = "Cannot upload to Local Folder";
                InformationPopupWindow.Show();
                return;
            }

            // Show the Add File Popup
            ShowUploadPopup(objFolder);
        }

        private void ShowUploadPopup(Folder objFolder)
        {
            // ** Values passed in the Header
            // p = portal
            // m = moduleid
            // u = UserId
            // f = folderid
            // tp = password

            StringBuilder AdditionalParamaters = new StringBuilder();
            AdditionalParamaters.Append("?");
            AdditionalParamaters.Append("p=" + intPortalID.ToString());
            AdditionalParamaters.Append("&m=" + intModuleID.ToString());
            AdditionalParamaters.Append("&u=" + intUserID.ToString());
            AdditionalParamaters.Append("&f=" + objFolder.FolderID.ToString());
            AdditionalParamaters.Append("&tp=" + strPassword);

            Uri uri = new Uri(strWebServiceBase + "FileUpload.ashx" + AdditionalParamaters.ToString(), UriKind.Absolute);
            FileUploadPopupWindow.uploadControl.UploadUrl = uri;
            FileUploadPopupWindow.uploadControl.UploadChunkSize = 4194304;
            FileUploadPopupWindow.uploadControl.ResizeImage = false;
            FileUploadPopupWindow.uploadControl.files.Clear();

            FileUploadPopupWindow.Show();
        }

        private void FileUploadPopup_Closed(object sender, EventArgs e)
        {
            FileUploadPopupWindow.uploadControl.ResetControl();
            // Refresh the File list
            DisplayFilesInFolder();
        }
        #endregion

        // Drag and Drop
        private List<UserControl> colUserControl = new List<UserControl>();
        private Panel OriginalParentPanel;
        private Point OriginalStartingDragPoint;
        private Point StartingDragPoint;

        #region UpdateElementPosition
        private void UpdateElementPosition(FrameworkElement objFrameworkElement, Point Point)
        {
            Canvas.SetLeft(objFrameworkElement, Point.X - StartingDragPoint.X);
            Canvas.SetTop(objFrameworkElement, Point.Y - StartingDragPoint.Y);
        }
        #endregion

        #region MoveToTop
        private void MoveToTop(FrameworkElement objFrameworkElement)
        {
            Panel objPanel = (Panel)objFrameworkElement.Parent;

            //Find the highest elemnt
            int intHighestElement = 0;
            foreach (UIElement UIElement in objPanel.Children)
            {
                int intTmpHighestElement = Canvas.GetZIndex(UIElement);
                intHighestElement = (intTmpHighestElement > intHighestElement) ? intTmpHighestElement : intHighestElement;
            }

            Canvas.SetZIndex(objFrameworkElement, intHighestElement + 1);
        }
        #endregion

        #region MouseLeftButtonDown
        public void objFrameworkElement_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // Get the File object
            FileObject objCurrentFileObject = (FileObject)sender;

            // Remove the element from it's control and move it to the parent
            // if it's Tag contains the words [draggable-movable]
            if (objCurrentFileObject.Tag.ToString().Contains("[draggable-movable]"))
            {
                // Remove Hover and SlectedFile from all other FileObjects in the Parent WrapPanel
                foreach (var item in this.FileDetailList.FilesInList.Children)
                {
                    // Get the File object
                    FileObject objFileObject = (FileObject)item;
                    // Set it to not be the selected file
                    objFileObject.SeletedFile = false;
                    // Remove the Hover State
                    objFileObject.GoToStateNoHover();
                }

                // Set the Current File to be the Selected File
                objCurrentFileObject.SeletedFile = true;
                objCurrentFileObject.GoToStateToUnHover();
                objCurrentFileObject.FileObjectFileName.Text = objCurrentFileObject.ShortFileName;
                objCurrentFileObject.FileObjectFileName.FontSize = Convert.ToDouble(9.5);

                OriginalParentPanel = objCurrentFileObject.Parent as Panel;
                OriginalStartingDragPoint = e.GetPosition(OriginalParentPanel);

                // Create a New File Object to use for the Drag
                FileObject objNewFileObject = new FileObject(FormatFileName(objCurrentFileObject.FullFileName), objCurrentFileObject.IsLocal);
                objNewFileObject.IsLocal = objCurrentFileObject.IsLocal;
                objNewFileObject.FileID = objCurrentFileObject.FileID;
                objNewFileObject.FullFileName = objCurrentFileObject.FullFileName;
                objNewFileObject.ShortFileName = FormatFileName(objCurrentFileObject.FullFileName);
                objNewFileObject.LocalFileNameAndPath = objCurrentFileObject.LocalFileNameAndPath;
                objNewFileObject.MouseLeftButtonDown += new MouseButtonEventHandler(objFrameworkElement_MouseLeftButtonDown);

                if (objCurrentFileObject.IsLocal)
                {
                    //A Local file
                    ToolTipService.SetToolTip(objCurrentFileObject.DownloadIcon, "");
                    objCurrentFileObject.DownloadIcon.Visibility = Visibility.Collapsed;
                    objCurrentFileObject.lnkDownload.Visibility = Visibility.Collapsed;
                }
                else
                {
                    // A server file
                    objNewFileObject.lnkDownload.NavigateUri = objCurrentFileObject.lnkDownload.NavigateUri;
                }

                this.LayoutRoot.Children.Add(objNewFileObject);
                objNewFileObject.CaptureMouse();

                // Set the starting point for the drag
                StartingDragPoint = e.GetPosition(objCurrentFileObject);
                MoveToTop(objNewFileObject);
                UpdateElementPosition(objNewFileObject, e.GetPosition(this.LayoutRoot));

                objNewFileObject.MouseMove += new MouseEventHandler(objFrameworkElement_MouseMove);
                objNewFileObject.MouseLeftButtonUp += new MouseButtonEventHandler(objFrameworkElement_MouseLeftButtonUp);
            }

        }
        #endregion

        // Move File

        #region MouseMove
        void objFrameworkElement_MouseMove(object sender, MouseEventArgs e)
        {
            FrameworkElement objFrameworkElement = (FrameworkElement)sender;
            Canvas objCanvas = (Canvas)objFrameworkElement.Parent;
            Point Point = e.GetPosition(objCanvas);

            UpdateElementPosition(objFrameworkElement, Point);

            if (objFrameworkElement.Tag.ToString().Contains("[draggable-movable]"))
            {
                FileObject objFileObject = (FileObject)objFrameworkElement;
                Point tmpPoint = e.GetPosition(null);

                // Build a list of elements at the current mouse position
                List<UIElement> hits = (List<UIElement>)System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(tmpPoint, this);

                StackPanel tmpStackPanel = new StackPanel();
                var TreeStackPanels = from element in hits
                                      where element.GetType() == tmpStackPanel.GetType()
                                      select element;

                if (TreeStackPanels != null)
                {
                    int intFolderID = 0;
                    foreach (var TreeStackPanel in TreeStackPanels)
                    {
                        StackPanel objStackPanel = (StackPanel)TreeStackPanel;
                        if (objStackPanel.Name == "TreeFolder")
                        {
                            // We found a StackPanel that is in a Tree
                            // This means we have found a Tree Node
                            intFolderID = Convert.ToInt32(objStackPanel.Tag.ToString());

                            // Only show the details of the folder if we are not already showing it
                            if (intFolderID != CurrentlySelectedFolderID)
                            {
                                // Programatically Select Tree Node
                                ProgramaticallySelectTreeNode(intFolderID);
                                DisplayFilesInFolder();
                            }
                        }
                    }
                }
            }
        }
        #endregion

        // Drop file

        #region MouseLeftButtonUp
        void objFrameworkElement_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            //Stop Drag
            FrameworkElement objFrameworkElement = (FrameworkElement)sender;
            objFrameworkElement.ReleaseMouseCapture();

            objFrameworkElement.MouseMove -=
                new MouseEventHandler(objFrameworkElement_MouseMove);
            objFrameworkElement.MouseLeftButtonUp -=
                new MouseButtonEventHandler(objFrameworkElement_MouseLeftButtonUp);

            // If it is an element marked [draggable-movable] it is a file we are dragging
            if (objFrameworkElement.Tag.ToString().Contains("[draggable-movable]"))
            {
                FileObject objFileObject = (FileObject)objFrameworkElement;
                Point tmpPoint = e.GetPosition(null);
                // Build a list of elements at the current mouse position
                List<UIElement> hits = (List<UIElement>)System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(tmpPoint, this);

                // Are we over the TreeView
                var FilesFolderTree = from element in hits
                                      where element == FolderTree
                                      select element;

                // To drop a file we need to be over the TreeView
                if (FilesFolderTree.Count() > 0)
                {
                    int intFolderID = CurrentlySelectedFolderID;

                    // A server File
                    if (objFileObject.FileID > -1)
                    {
                        // Dropping on a Server Folder
                        if (intFolderID > -1)
                        {
                            // Call the web service to move the file to the new folder
                            WebServiceSoapClient objWebServiceSoapClient = new WebServiceSoapClient();
                            EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceBase + "Webservice.asmx");
                            objWebServiceSoapClient.Endpoint.Address = MyEndpointAddress;

                            objWebServiceSoapClient.UpdateFileFolderCompleted +=
                                new EventHandler<UpdateFileFolderCompletedEventArgs>(objWebServiceSoapClient_UpdateFileFolderCompleted);
                            objWebServiceSoapClient.UpdateFileFolderAsync(intPortalID, intModuleID, intUserID, strPassword, intFolderID, objFileObject.FileID);
                        }
                        else
                        {
                            // Dropping onto a Local folder
                            MessageBox.Show("To move a file locally, hover over it, and click the Green arrow to download it");
                        }
                    }
                    else
                    {
                        // A Local File

                        // Dropping on a Server Folder
                        if (intFolderID > -1)
                        {
                            // ** Values passed in the Header
                            // p = portal
                            // m = moduleid
                            // u = UserId
                            // f = folderid
                            // tp = password

                            StringBuilder AdditionalParamaters = new StringBuilder();
                            AdditionalParamaters.Append("?");
                            AdditionalParamaters.Append("p=" + intPortalID.ToString());
                            AdditionalParamaters.Append("&m=" + intModuleID.ToString());
                            AdditionalParamaters.Append("&u=" + intUserID.ToString());
                            AdditionalParamaters.Append("&f=" + intFolderID.ToString());
                            AdditionalParamaters.Append("&tp=" + strPassword);

                            Uri uri = new Uri(strWebServiceBase + "FileUpload.ashx" + AdditionalParamaters.ToString(), UriKind.Absolute);
                            FileUploadPopupWindow.uploadControl.UploadUrl = uri;
                            FileUploadPopupWindow.uploadControl.UploadChunkSize = 4194304;
                            FileUploadPopupWindow.uploadControl.ResizeImage = false;
                            FileUploadPopupWindow.uploadControl.files.Clear();

                            // Add the file to upload
                            FileInfo objFile = new FileInfo(objFileObject.LocalFileNameAndPath);
                            DC.FileUpload.FileUpload objFileUpload = new DC.FileUpload.FileUpload(FileUploadPopupWindow.Dispatcher, uri, objFile);
                            FileUploadPopupWindow.uploadControl.files.Add(objFileUpload);

                            FileUploadPopupWindow.Show();
                        }
                        else
                        {
                            // Dropping on a Local folder
                            MoveLocalFileLocally(objFrameworkElement, objFileObject, intFolderID);
                        }
                    }
                }

                // Remove the temporary dragging element from the main canvas
                this.LayoutRoot.Children.Remove(objFrameworkElement);
            }
        }

        #region MoveLocalFileLocally
        private void MoveLocalFileLocally(FrameworkElement objFrameworkElement, FileObject objFileObject, int intFolderID)
        {
            // Get the full path of the folder

            // Get the Root Folders in the Tree
            // This will return the Local folder and the Main server folder
            IEnumerable<FileManager.Files.Folder> colFolders =
                (IEnumerable<FileManager.Files.Folder>)FolderTree.Items.Cast<Files.Folder>();

            // Search the children of the Local Folder
            // for a folder with the selected FolderID
            var DropFolder = (from Folders in colFolders.Where(x => x.FolderID == -1).FirstOrDefault().GetAllFolders()
                              where Folders.FolderID == intFolderID
                              select Folders).FirstOrDefault();

            if (DropFolder == null)
            {
                // If it's null it must be a root folder
                DropFolder = colFolders.Where(x => x.FolderID == intFolderID).FirstOrDefault();
            }

            string DestinationFolderPath = DropFolder.FullPath;
            string CurrentFileNameAndPath = objFileObject.LocalFileNameAndPath;

            // Move the file
            try
            {
                File.Move(CurrentFileNameAndPath, DestinationFolderPath + "\\" + objFileObject.FullFileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                // Remove the temporary dragging element from the main canvas
                this.LayoutRoot.Children.Remove(objFrameworkElement);
            }

            // Programatically Select Tree Node
            ProgramaticallySelectTreeNode(intFolderID);
            DisplayFilesInFolder();
        }
        #endregion

        void objWebServiceSoapClient_UpdateFileFolderCompleted(object sender, UpdateFileFolderCompletedEventArgs e)
        {
            // If the result is not empty
            // it will contain the folder the file was mob=ved to
            if (e.Result != "")
            {
                // Get the FolderID
                int intFolderID = Convert.ToInt32(e.Result);

                // Programatically Select Tree Node
                ProgramaticallySelectTreeNode(intFolderID);
                DisplayFilesInFolder();
            }
        }
        #endregion

        #region ProgramaticallySelectTreeNode
        private void ProgramaticallySelectTreeNode(int intFolderID)
        {
            Folder DropFolder = null;
            // Get the Root Folders in the Tree
            // This will return the Local folder and the Main server folder
            IEnumerable<FileManager.Files.Folder> colFolders =
                (IEnumerable<FileManager.Files.Folder>)FolderTree.Items.Cast<Files.Folder>();

            if (intFolderID < 0)
            {
                // Search the children of the Local Folder
                // for a folder with the selected FolderID
                DropFolder = (from Folders in colFolders.Where(x => x.FolderID == -1).FirstOrDefault().GetAllFolders()
                              where Folders.FolderID == intFolderID
                              select Folders).FirstOrDefault();
            }
            else
            {
                // Search the children of the Server Folder
                // for a folder with the selected FolderID
                DropFolder = (from Folders in colFolders.Where(x => x.FolderID > 0).FirstOrDefault().GetAllFolders()
                              where Folders.FolderID == intFolderID
                              select Folders).FirstOrDefault();
            }

            if (DropFolder == null)
            {
                // If it's null it must be a root folder
                DropFolder = colFolders.Where(x => x.FolderID == intFolderID).FirstOrDefault();
            }

            // Set the Folder as the selected folder in the tree
            CurrentlySelectedFolderID = DropFolder.FolderID;
            FolderTree.SelectItem(DropFolder);
            FolderTree.UpdateLayout();
        }
        #endregion


        //protected override void OnDrop(DragEventArgs e)
        //{
        //    base.OnDrop(e);

        //    var win = new ChildWindow();
        //    win.Content = "Dropped to MainPage: " + e.OriginalSource;
        //    win.Show();

        //    Point tmpPoint = e.GetPosition(this);

        //    // Build a list of elements at the current mouse position
        //    List<UIElement> hits = (List<UIElement>)System.Windows.Media.
        //        VisualTreeHelper.FindElementsInHostCoordinates(tmpPoint, this);

        //    // Are we over the TreeView
        //    var FilesFolderTree = from element in hits
        //                          where element == FileDetailList
        //                          select element;

        //    if (FilesFolderTree.Count() > 0)
        //    {
        //        var fileWin = new ChildWindow();
        //        fileWin.Content = "Dropped on file list";
        //        fileWin.Show();
        //    }
        //    e.Handled = true;
            
        //}




    }
}